#include "aichess.h"
#include <QMessageBox>
#include <QMouseEvent>
#include <QDebug>
#include "stone.h"

AIchess::AIchess()
{

}

void AIchess::mousePressEvent(QMouseEvent *event)
{
    int row,row2;
    int col,col2;
    if(event->button() == Qt::LeftButton)
    {
        //鼠标点击位置对应棋盘的行列值
        row=(event->y()-starty)/d;
        col=(event->x()-startx)/d;
    }
    //选中棋子的行列值
    row2=(sto[selected_id].y-starty)/d;
    col2=(sto[selected_id].x-startx)/d;
    if(is_selected)//有棋子被选中
    {
        if(!canMove(row,col)) //判断是否出界
        {
            QMessageBox::warning(this,"注意棋盘范围","暗度陈仓？想得美！");
            return;
        }
        else if(!canMove2(row,row2,col,col2)) //判断是否飞棋
        {
            QMessageBox::warning(this,"不能一次性走多格","干啥，开挂呢？");
            return;
        }
        else if(!canMove3(row,col,selected_id)) //判断是否想直接吃子
        {
            QMessageBox::warning(this,"你不能直接吃子","哪有你这么玩的？");
            return;
        }
        else //没有违反规则
        {
            for(int i=6;i!=selected_id && i<12;i++)//又选中了自己方的棋子，说明要换
            {
                if(row==(sto[i].y-starty)/d //横坐标相等
                        && (col==(sto[i].x-startx)/d //纵坐标相等
                        && sto[i].is_dead==false)) //没有死
                {
                    //更新所选棋子
                    selected_id = i;
                    lastid = i;
                    is_selected = true;
                    update();
                    return;
                }
            }
        }
        //千辛万苦，可以行棋了

        sto[selected_id].x = startx + col * d;
        sto[selected_id].y = starty + row * d;
        update();
        chizi(sto,selected_id);

        if(lastid>=6 && lastid<12 && is_selected)
        {
            int a=computerMove(sto);
            chizi(sto,a);
            lastid=6;
        }

        lastid = selected_id;
        //还原成未选状态
        is_selected = false;
        selected_id = -1;
    }
    else//没有棋子被选中
    {
        for(int i=6;i<12;i++)
        {
            if((sto[i].y-starty)/d==row && (sto[i].x-startx)/d==col && sto[i].is_dead==false)
            {
                //记录下来
                selected_id = i;
                lastid = i;
                is_selected = true;
                update();
            }
        }
    }
}

int AIchess::computerMove(stone sto[])
{
    int score[6][4];//存有 共24种可能走法的分值
    for(int i=0;i<6;i++)//遍历电脑方棋子
    {
        if(sto[i].is_dead)
        {
            continue;
        }
        if(canMove4(sto,i,0))
        {
            zuo(sto,i); //试着往左移一下
            score[i][0]=getScore(sto,i,0);//获取局面分
            you(sto,i); //赶紧恢复棋盘
        }

        if(canMove4(sto,i,1))
        {
            you(sto,i);
            score[i][1]=getScore(sto,i,1);
            zuo(sto,i);
        }

        if(canMove4(sto,i,2))
        {
            shang(sto,i);
            score[i][2]=getScore(sto,i,2);
            xia(sto,i);
        }

        if(canMove4(sto,i,3))
        {
            xia(sto,i);
            score[i][3]=getScore(sto,i,3);
            shang(sto,i);
        }
    }
    //所有走法均已存入数组，现在要挑出最好的一种
    int maxscore = -1,ii=0,jj=0,movenum=0;
    for(int i=0;i<6;i++)
    {
        if(sto[i].is_dead)
        {
            continue;
        }
        for(int j=0;j<4;j++)
        {
            if(score[i][j]>=maxscore && canMove4(sto,i,j))
            {
                maxscore = score[i][j];
                ii=i;
                jj=j;
                movenum = i;
            }
        }
    }
    if(jj==0)
    {
        zuo(sto,ii);
    }
    if(jj==1)
    {
        you(sto,ii);
    }
    if(jj==2)
    {
        shang(sto,ii);
    }
    if(jj==3)
    {
        xia(sto,ii);
    }
    return movenum;
}

void AIchess::zuo(stone sto[],int num)
{
    sto[num].x -= d;
}

void AIchess::you(stone sto[],int num)
{
    sto[num].x += d;
}

void AIchess::shang(stone sto[],int num)
{
    sto[num].y -=d;
}

void AIchess::xia(stone sto[],int num)
{
    sto[num].y += d;
}

int AIchess::getScore(stone sto[],int num,int moveway)
{
    int score = 0;
    if(can_chizi(sto,num))
    {
        if(num==2 || num==3) //横向走形成吃子
            score += 200000;  //再好不过了，狂加分
        if(num==0 || num==1)
            score += 150000;
    }
    for(int i=0;i<6;i++)
    {
        if(sto[i].is_dead)
        {
            continue;
        }
        zuo(sto,i);//试着左移一步
        if(can_chizi(sto,i))//能吃子
        {
            score += 20;//小加20分
        }
        you(sto,i);//赶紧还原

        you(sto,i);
        if(can_chizi(sto,i))
        {
            score += 20;
        }
        zuo(sto,i);

        shang(sto,i);
        if(can_chizi(sto,i))
        {
            score += 20;
        }
        xia(sto,i);

        xia(sto,i);
        if(can_chizi(sto,i))
        {
            score += 20;
        }
        shang(sto,i);
    }
    if(sto[num].x==startx+d*3 && moveway==0)//往中间走，小加几分
    {
        score += 2;
    }
    if(sto[num].x==startx && moveway==1)
    {
        score += 2;
    }
    if(sto[num].y==starty+d*3 && moveway==2)
    {
        score += 4;
    }
    if(sto[num].y==starty && moveway==3)
    {
        score += 4;
    }

    return score;
}

bool AIchess::canMove4(stone sto[],int movenum,int move_way)
{
    int row=(sto[movenum].y-starty) / d;
    int col=(sto[movenum].x-startx) / d;
    if(row==0) if(move_way==2) return false;
    if(row==3) if(move_way==3) return false;
    if(col==0) if(move_way==0) return false;
    if(col==3) if(move_way==1) return false;
    for(int i=0;i<12;i++)
    {
        if(sto[i].is_dead)
        {
            continue;
        }
        if(move_way==0 && (sto[i].x-startx)/d==col-1 && (sto[i].y-starty)/d==row)
            return false;
        if(move_way==1 && (sto[i].x-startx)/d==col+1 && (sto[i].y-starty)/d==row)
            return false;
        if(move_way==2 && (sto[i].y-starty)/d==row-1 && (sto[i].x-startx)/d==col)
            return false;
        if(move_way==3 && (sto[i].y-starty)/d==row+1 && (sto[i].x-startx)/d==col)
            return false;
    }
    return true;
}

bool AIchess::can_chizi(stone sto[],int moveid)
{
    int rowarr[12], colarr[12];//分别存储每颗棋子在棋盘上的横纵坐标
    for(int i=0;i<12;i++)
    {
        rowarr[i] = (sto[i].y - starty) / d;
        colarr[i] = (sto[i].x - startx) / d;
    }
    int count_row = 0, count_col = 0;//记录该行该列上各有几颗棋子
    int row = (sto[moveid].y - starty) / d;
    int col = (sto[moveid].x - startx) / d;
    for(int i=0;i<12;i++)
    {
        if(sto[i].is_dead)
        {
            continue;
        }
        if(rowarr[i]==row && sto[i].is_dead == false)
        {
            count_row++;
        }
        if(colarr[i]==col && sto[i].is_dead == false)
        {
            count_col++;
        }
    }
    if(count_row==3)//这一行有机会
    {
        for(int i=0;i<6;i++)//遍历找一下这一行的活盟友
        {
            if(sto[i].is_dead)
            {
                continue;
            }
            if(colarr[i]-col == 1 && rowarr[i]==row) //右边有盟友
            {
                for(int j=6;j<12;j++)//看一下左边一格或右边两格有无敌子
                {
                    if(sto[j].is_dead)
                    {
                        continue;
                    }
                    if(colarr[j]-col == -1 && rowarr[j]==row)//找到了
                    {
                        return true;
                    }
                    if(colarr[j]-col == 2 && rowarr[j]==row)//找到了
                    {
                        return true;
                    }
                }
            }
            if(colarr[i]-col == -1 && rowarr[i]==row)//左边有盟友
            {
                for(int j=6;j<12;j++)//看一下左边两格或右边一格有无敌子
                {
                    if(sto[j].is_dead)
                    {
                        continue;
                    }
                    if(colarr[j]-col == 1 && rowarr[j]==row)//找到了
                    {
                        return true;
                    }
                    if(colarr[j]-col == -2 && rowarr[j]==row)//找到了
                    {
                        return true;
                    }
                }
            }
        }
    }
    if(count_col==3)//这一列有机会
    {
        for(int i=0;i<6;i++)//遍历找一下这一列的盟友
        {
            if(sto[i].is_dead)
            {
                continue;
            }
            if(rowarr[i]-row == 1 && colarr[i]==col)//下边有盟友
            {
                for(int j=6;j<12;j++)//看一下上边一格或下边两格有无敌子
                {
                    if(sto[j].is_dead)
                    {
                        continue;
                    }
                    if(rowarr[j]==row-1 && colarr[j]==col)//找到了
                    {
                        return true;
                    }
                    if(rowarr[j]==row+2 && colarr[j]==col)//找到了
                    {
                        return true;
                    }
                }
            }
            if(rowarr[i]-row == -1 && colarr[i]==col)//上边有盟友
            {
                for(int j=6;j<12;j++)//看一下上边两格或下边一格有无敌子
                {
                    if(sto[j].is_dead)
                    {
                        continue;
                    }
                    if(rowarr[j]==row+1 && colarr[j]==col)//找到了
                    {
                        return true;
                    }
                    if(rowarr[j]==row-2 && colarr[j]==col)//找到了
                    {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}
